package definition;

import domain.User;
import org.junit.Test;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;

/**
 * 2种方式构建 BeanDefinition
 * @author jackcfan
 * @date 2021/9/12
 */
public class BeanDefinitionCreateTest {

    /**
     * 通过 BeanDefinitionBuilder 构建 BeanDefinition
     * */
    @Test
    public void testBeanDefinitionBuilder(){
        /**
         * 通过 BeanDefinitionBuilder 构建
         * 内部使用 {@link org.springframework.beans.factory.support.GenericBeanDefinition}
         * GenericBeanDefinition -> AbstractBeanDefinition -> BeanDefinition
         * */
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(User.class);

        /*
        <bean id="user-by-static-method" class="domain.User" scope="singleton" primary="true">
            <property name="id" value="1"></property>
            <property name="name" value="spring builder"></property>
        </bean>
        */
        // 设置属性
        builder.addPropertyValue("id",1)
                .addPropertyValue("name","spring builder")
                .setScope(BeanDefinition.SCOPE_SINGLETON)
                .setPrimary(true);

        BeanDefinition beanDefinition = builder.getBeanDefinition();
        System.out.println(beanDefinition);

        // 注册到容器
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.registerBeanDefinition("user", beanDefinition);

        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);

    }

    /**
     * 通过 GenericBeanDefinition 构建 BeanDefinition
     * */
    @Test
    public void testGenericBeanDefinition(){
        // 直接使用 GenericBeanDefinition，不通过 builder
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();

        // 设置 Bean 类型
        beanDefinition.setBeanClass(User.class);

        // 通过 MutablePropertyValues 批量操作属性
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        propertyValues.add("id", 1)
                        .add("name", "spring builder");
        // 通过 set MutablePropertyValues 批量操作属性
        beanDefinition.setPropertyValues(propertyValues);

        System.out.println(beanDefinition);
    }

    /**
     * RootBeanDefinition 不能继承其他 Bean
     * {@link RootBeanDefinition#setParentName(String)} 会抛出异常
     * */
    @Test
    public void testRootBeanDefinition(){
        RootBeanDefinition beanDefinition = new RootBeanDefinition();

        // 设置 Bean 类型
        beanDefinition.setBeanClass(User.class);

        // 通过 MutablePropertyValues 批量操作属性
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        propertyValues.add("id", 1)
                .add("name", "spring builder");
        // 通过 set MutablePropertyValues 批量操作属性
        beanDefinition.setPropertyValues(propertyValues);

        System.out.println(beanDefinition);
    }
}
